﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace FCAF{
    public class CommModule {
        public enum commandTypes {
            LIN, 
            LOUT,
            VER,
            LCDON,
            LCDOFF,
            NONE
        };
        private commandTypes    _lastCommandType    = commandTypes.NONE;
        private bool            _awaitingResponse   = false;

        private string          _sessionID          = "";
        private string          _UID                = "";
        private string          _PWD                = "";

        private SerialPort      _xbee               = new SerialPort();
        private string          _commPort           = "";
        private const int       _baudrate           = 9600;
        
        
        private string              _lastResponseReceived = "";
        private string[]            _responseArray = new string[5];
        public event EventHandler   ResponseArrived;

        public CommModule(string commPort, string UID, string PWD) {
            _commPort = commPort; 
            _UID = UID; 
            _PWD = PWD;

            _xbee.DataReceived +=new SerialDataReceivedEventHandler(_xbee_DataReceived);
            _xbee.ErrorReceived +=new SerialErrorReceivedEventHandler(_xbee_ErrorReceived);
            
            _xbee.PortName      = commPort;
            _xbee.BaudRate      = _baudrate;
            _xbee.ReadTimeout   = 5000;
            _xbee.WriteTimeout  = 5000;

            try {
                _xbee.Open();
            } catch {
            } finally {
            }
        }

        ~CommModule() {
            _xbee.Close();
        }

        // 
        // private methods
        //
        private bool _isCommOpen() {
            return _xbee.IsOpen; 
        }

        private bool _sendCommCommand(commandTypes commandToSend, string param1, string param2, string param3, string param4) {
            string commandString        = "";
            _lastResponseReceived       = "";
            _lastCommandType            = commandToSend;
            _awaitingResponse           = true;

            if (_isCommOpen()) {
                switch (commandToSend) {
                    case commandTypes.LIN:
                        commandString   = "LIN:" + param1 + ":" + param2 + ":" + param3 + ":" + param4; 
                        break;
                    case commandTypes.LOUT:
                        commandString = "LOUT:";
                        break;
                    default:
                        _awaitingResponse = false;
                        commandString ="";
                        break;
                }
            }    
            if (commandString != "") {
                _xbee.WriteLine(commandString);
                return true;
            }
            else
                return false;
        }



        //
        // public methods
        //
        public string lastResponseReceived {
            get {  return _lastResponseReceived; }
        }

        public commandTypes lastCommandType {
            get { return _lastCommandType; }
        }
        
        
        //
        // Comm Module Event Handlers.
        //
        protected virtual void _onResponseArrived(EventArgs e) {
            if (ResponseArrived != null) {
                ResponseArrived(_lastResponseReceived, e);
            }
        }
        private void _xbee_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) {
 	        throw new NotImplementedException();
        }
        private void  _xbee_DataReceived(object sender, SerialDataReceivedEventArgs e){
            _lastResponseReceived = "";
            SerialPort _xbee = (SerialPort)sender;
            string s = _xbee.ReadLine().Trim();
            _lastResponseReceived = s;

            _parseCommResponse(s);
            switch (_lastCommandType) {
                case commandTypes.LIN:
                    if (_responseArray[0] == "LIN-OK"){
                        _sessionID = _responseArray[1];
                    }
                    break;
                case commandTypes.LOUT:
                    if (_responseArray[0] == "LOUT-OK"){
                        _sessionID ="";
                    }
                    break;
                default:
                    break;
            }

            _awaitingResponse = false;
            _onResponseArrived(EventArgs.Empty);
        }

        private void _parseCommResponse(string sentence){
            _responseArray = sentence.Split(new Char[] { ':'});
            foreach (string s in _responseArray){
                if (s.Trim() != "")
                    Console.WriteLine(s);
            }
        }
    }
 }


